local tools = require 'util/tools'
local gempower = require 'util/obrsword_gempower'
local SourceModifierList = require("util/sourcemodifierlist")

local function clamp(value, min, max)
    if value < min then
        return min
    elseif value > max then
        return max
    else
        return value
    end
end
local function spawnfx(inst, fx)
    local x, y, z = inst.Transform:GetWorldPosition()
    -- SpawnPrefab(fx).Transform:SetPosition(x,-10,z)
    SpawnPrefab(fx).Transform:SetPosition(x, 4, z)
end

local skillobr = {}

skillobr.normal_attack = TUNING.Obrsword_nadamage
skillobr.LASER_COOLDOWN = 10
skillobr.bosslist = { "dragonfly", "moose", "antlion" }
function skillobr.checkboss(target)
    for _, value in ipairs(skillobr.bosslist) do
        if value == target.prefab then
            return true
        end
    end
end

function skillobr.checkbossdeath(inst, owner, target)
    if not skillobr.checkboss(target) then return end
    --  print("--判断是否的为元素boss")
    inst.deathtask = inst:ListenForEvent("death", function()
        local op = owner.components.obrsword_power
        if target.prefab == "dragonfly" and not op.dragonfly then
            op.dragonfly = true
        elseif target.prefab == "moose" and not op.moose then
            op.moose = true
        elseif target.prefab == "antlion" and not op.antlion then
            op.antlion = true
        end
    end, target)
end

function skillobr.OnAttack(inst, owner, target)
    gempower.checkandchange(owner, target, inst) -- 判断黄宝石
    skillobr.checkbossdeath(inst, owner, target) -- 判断是否的为元素boss
    if owner.components.obrsword_power.current >= 85 then
        if target ~= nil and target:IsValid() then
            SpawnPrefab("hitsparks_fx"):Setup(owner, target)
        end
    end
    SpawnPrefab("swap_obrsword_fx").Transform:SetPosition(owner.Transform:GetWorldPosition())
    -- 能量回复效果
    if target.components.health then
        local max = target.components.health.maxhealth
        owner.components.obrsword_power:DoDelta(3 + clamp(0.003 * max, 0, 8))
    end
    if TUNING.Obrsword_navoice then
        inst.SoundEmitter:PlaySound("obrost/obr/obrhit1") --普通攻击音效
    end
end

local function ApplyDamageReduction(inst, duration, reduction_percentage)
    -- 计算修饰符值，95%免伤意味着伤害减少到5%
    local modifier_value = reduction_percentage / 100

    -- 设置修饰符
    inst.components.health.externalabsorbmodifiers:SetModifier(inst, modifier_value, "damage_reduction")

    -- 使用计时器在duration秒后移除修饰符
    inst:DoTaskInTime(duration, function()
        inst.components.health.externalabsorbmodifiers:RemoveModifier(inst, "damage_reduction")
    end)
end
function skillobr.absord(caster)
    if not caster.components.health then
        return
    end

    ApplyDamageReduction(caster, 3, 95)
end

function skillobr.OnAttacknife(inst, owner, target)
    if target ~= nil and target:IsValid() then
        SpawnPrefab("shadowstrike_slash_fx").Transform:SetPosition(target.Transform:GetWorldPosition())
    end
    -- 能量额外附加伤害
    local lightdamage = owner.components.obrsword_power.obrsword_power_damage
    if target.components.health then
        target.components.health:DoDelta(-lightdamage)
    end
    if owner.components.obrsword_power.current > 12 and target.components.health then
        target.components.health:DoDelta(-120)
    end

    -- 能量回复效果
    if target:HasTag("monster") and target.components.health then
        local current = target.components.health.currenthealth
        owner.components.obrsword_power:DoDelta(1 + clamp(0.003 * current, 0, 6))
    end
    -- 能量扣除机制

    owner.components.obrsword_power:DoDelta(-12)

    -- 发射音效
    inst:DoTaskInTime(0.1, function()
        inst.SoundEmitter:PlaySound("dontstarve/wilson/fireball_explo")
    end)
end

---
---普通设置
function skillobr.normalsword(inst)
    if inst.components.weapon then
        inst:RemoveComponent("weapon")
    end
    if inst.components.spellcaster then
        inst:RemoveComponent("spellcaster")
    end
    --[[- if inst.components.rechargeable then

            inst:RemoveComponent("rechargeable")
        end]] --
    -- TUNING.swordtype = 0
    inst:AddComponent("weapon")
    print("swordtype", TUNING.swordtype)
    print("当前基础攻击是", skillobr.normal_attack)
    inst.components.weapon:SetDamage(TUNING.Obrsword_nadamage)
    -- inst.components.weapon:SetRange(1)
    -- inst.components.weapon:SetProjectile("sword_fire_projectile") -- 添加抛射物
    inst.components.weapon:SetOnAttack(skillobr.OnAttack)
end

function skillobr.originalsword(inst) -- 初始化一条龙
    skillobr.normalsword(inst)
    inst.SoundEmitter:PlaySound("obr_powerchange/op/sword")
    spawnfx(inst, "obrsword_powerchange_normal")
    TUNING.swordtype = 0
end

-- 小技能远程光刃
function skillobr.lightkinfe(inst)
    if not inst.components.weapon then
        inst:AddComponent("weapon")
    end

    inst.components.weapon:SetDamage(3)
    inst.components.weapon:SetRange(12, 14)

    inst.components.weapon:SetProjectile("power_knife") -- 添加抛射物
    inst.components.weapon:SetOnAttack(skillobr.OnAttacknife)
end

---四元素技能施法技能

--------------火元素
function skillobr.onfireattack(inst, owner, target, skipsanity)
    SpawnPrefab("attackfire_fx").Transform:SetPosition(target.Transform:GetWorldPosition())

    --  if not target.components.wuyi_karma then target:AddComponent("wuyi_karma") end
    -- SpawnPrefab("obrsword_powerchange_burst").Transform:SetPosition(inst.Transform:GetWorldPosition())
    inst.SoundEmitter:PlaySound("obr_powerchange/op/burst")
    -- target.components.wuyi_karma:DoDelta(2)
    inst:DoTaskInTime(0.1, function()
        inst.SoundEmitter:PlaySound("dontstarve/wilson/fireball_explo")
    end)

    -- 超级无赖减速定身
    if target.components.health then
        target.components.health:DoDelta(-TUNING.fire_damage)
    end
    target:DoTaskInTime(0.1, function()
        if target.components.locomotor then
            target.components.locomotor.externalspeedmultiplier = 0.2
        else
            if target.components.health then
                target.components.health:DoDelta(-TUNING.dirt_damage)
            end
        end
    end)
    target:DoTaskInTime(5, function(target)
        if target ~= nil then
            target.components.locomotor.externalspeedmultiplier = 1
        end
    end)
    ----------------------------------打伤害部分
    ---三秒持续出伤
    local firebird = SpawnPrefab("sword_fx_firebird")
    firebird.entity:SetParent(target.entity)
    target.taskfire = target:DoPeriodicTask(0.3, function(target)
        if target.components.health then
            local max = target.components.health.maxhealth
            local damagesum = 65 + 0.008 * max
            target.components.health:DoDelta(-damagesum)
        end
    end)
    target:DoTaskInTime(3, function(target)
        if target.taskfire ~= nil then
            target.taskfire:Cancel()
            target.taskfire = nil
        end
        if target.components.health then -- 20%已损失生命值伤害
            local max = target.components.health.maxhealth
            local current = target.components.health.currenthealth
            local havelose = max - current
            local damagesum = 200 + 0.2 * havelose
            target.components.health:DoDelta(-damagesum)
        end
    end)
end

function skillobr.swordfire(staff, target, pos) -- 火技能释放
    local onfireattack = skillobr.onfireattack
    local caster = staff.components.inventoryitem.owner
    if caster.components.obrsword_power.current < TUNING.FIRECONSUE then
        return
    end
    -- caster.sg:GoToState("castspell")
    staff.SoundEmitter:PlaySound("obrost/obr/obrskillbgm3") -- 音效
    if caster ~= nil and caster:IsValid() then
        SpawnPrefab("tauntfire_fx").Transform:SetPosition(caster.Transform:GetWorldPosition())
    end
    -- 施法免伤增益
    skillobr.absord(caster)

    local inst = staff
    inst:AddComponent("weapon")
    inst.components.weapon:SetDamage(42)
    inst.components.weapon:SetRange(16, 18)
    inst.components.weapon:SetProjectile("sword_fire_projectile") -- 添加抛射物
    inst.components.weapon:SetOnAttack(onfireattack)              -- 加入武器效果
    --[[     if inst.components.wuyi_shield_val:Get() == 0 then
                local planardamage = inst:AddComponent("planardamage")
                planardamage:SetBaseDamage(10)
            end]] --
    if target:HasTag("_combat") and target:HasTag("_health") then
        caster.components.combat:DoAttack(target)

        if caster.components.obrsword_power ~= nil then
            caster.components.obrsword_power:DoDelta(-TUNING.FIRECONSUE)
        end
    end
    inst:DoTaskInTime(1, function(inst)
        skillobr.originalsword(inst)
    end)
    -- 技能附带效果：升温以及改动潮湿度
    if caster.components.temperature ~= nil then
        local current = caster.components.temperature:GetCurrent()
        if current == nil then
            return
        end

        if TheWorld.state.season == "winter" then
            caster.components.temperature:SetTemperature(65) -- 体温
        end
    end
    if caster.components.moisture then
        caster.components.moisture:SetPercent(0)
    end
end

-------------------------------水元素
--AOE  全体眩晕3.5s
-- 解除大部分仇恨，
--减弱攻击力,
--恢复owner双维45，
--可雇佣单位会被雇佣一天，
-- 并对三个可狂暴史诗级单位产生断筋伤害
-- 对暗影生物产生更多伤害以及更多减速（10s）
function skillobr.onwaterttack(inst, owner, target, skipsanity)
    -- 音效待定

    if target.brain then
        target.brain:Stop()
        target:DoTaskInTime(3.5, function(target)
            target.brain:Start()
        end)
    end
    local firebird = SpawnPrefab("weregoose_splash_med1")
    firebird.entity:SetParent(target.entity)
    inst:DoTaskInTime(1, function(staff)
        local firebird = SpawnPrefab("sword_fx_water2")
        firebird.entity:SetParent(target.entity)
    end)

    inst:DoTaskInTime(2, function(staff)
        local firebird = SpawnPrefab("sword_fx_water3")
        firebird.entity:SetParent(target.entity)
    end)
    -- 暗影/史诗级单位先产生伤害
    if target.components.health then
        if target:HasTag("epic") or target:HasTag("shadow") then
            if target.components.health then
                target.components.health:DoDelta(-TUNING.water_damage)
            end
        end
    end
    if target:HasTag("lavae") then
        target.components.freezable:AddColdness(4)
        target.components.freezable:SpawnShatterFX() -- 生成粉碎效果
    end
    -- 超级无赖减速,对暗影生物产生更多伤害
    
    if target.components.locomotor then
        target.components.locomotor.externalspeedmultiplier = 0.1
    else
        if target.components.health and target:HasTag("shadow") then
            target.components.health:DoDelta(-3 * TUNING.dirt_damage)
        end
    end

    target:DoTaskInTime(4, function(target)
        if target ~= nil and target.components.locomotor then
            target.components.locomotor.externalspeedmultiplier = 1
        end
    end)

    -- 解除非暗影与部分boss的仇恨（是的，除了龙蝇）

    if not target:HasTag("dragonfly") or target:HasTag("shadow") then
        if target.components.combat then
            target.components.combat:SetTarget(nil)
        end
    end
    -- 减攻15s
    if target.components.combat then
        target.components.combat.externaldamagemultipliers:SetModifier(target, 0.5, "water_less_damage")
        target:DoTaskInTime(15, function(target, attack)
            if target.components.health and target:IsValid() and target.components.combat then
                target.components.combat.externaldamagemultipliers:RemoveModifier(target, "water_less_damage")
            end
        end)
    end
    ---对可雇佣单位进行一天雇佣
    if target.components.follower then
        if target:HasTag("companion") or target:HasTag("glommer") then return end
        target.components.follower:SetLeader(owner)
        target.components.follower:AddLoyaltyTime(480)
    end
    -- 针对龙蝇 减速8s 已损失百分之6 减攻击力15s
    if target:HasTag("dragonfly") and target.components.health -- or (target:HasTag("deergemresistance") and target:HasTag("epic")) or target:HasTag("toadstool")
    then
        if target.components.moisture then
            target.components.moisture:SetPercent(100)
        end
        if target.components.health:GetPercent() < 0.15 and
            target.enraged == true
        then --简单的灌伤害
            local current = target.components.health.currenthealth
            local max = target.components.health.maxhealth
            local damagewater = (max - current) * 0.06 + TUNING.water_damage * 2
            target.components.health:DoDelta(-damagewater)

            if target.components.locomotor then
                target.components.locomotor.externalspeedmultiplier = 0.1
            end
            --8s减速
            target:DoTaskInTime(8, function(target)
                if target ~= nil and target.components.locomotor then
                    target.components.locomotor.externalspeedmultiplier = 1
                end
            end)
            --0.25攻击力
            if target.components.combat then
                target.components.combat.externaldamagemultipliers:SetModifier(target, 0.25, "water_less_damage")
                target:DoTaskInTime(15, function(target, attack)
                    if target.components.health and target:IsValid() and target.components.combat then
                        target.components.combat.externaldamagemultipliers:RemoveModifier(target, "water_less_damage")
                    end
                end)
            end
        end
    end
end

function skillobr.swordwater(staff, target, pos) -- 水技能释放
    local caster = staff.components.inventoryitem.owner
    if caster.components.obrsword_power.current >= TUNING.FIRECONSUE then
        -- 施法免伤增益
        skillobr.absord(caster)
        -- caster.sg:GoToState("castspell")
        staff.SoundEmitter:PlaySound("obrost/obr/obrwater") -- 水音效

        local firebird = SpawnPrefab("sword_fx_water")
        firebird.entity:SetParent(caster.entity)

        -- AOE处理

        local musttags = { "_health", "_combat" }
        local notags = { "player" }
        local pos = Vector3(caster.Transform:GetWorldPosition())
        local ents = TheSim:FindEntities(pos.x, pos.y, pos.z, 20, musttags, notags)
        for k, v in pairs(ents) do
            if v.components.health and v.components.combat then
                skillobr.onwaterttack(staff, caster, v)
            end
        end
        staff:DoTaskInTime(1, function(staff)
            if caster.components.obrsword_power ~= nil then
                caster.components.obrsword_power:DoDelta(-TUNING.FIRECONSUE)
            end

            -- 技能附带效果：平衡体温，恢复一定双维,控制潮湿度

            if caster.components.health then
                caster.components.health:DoDelta(45)
            end
            if caster.components.sanity then
                caster.components.sanity:DoDelta(45)
            end
            if caster.components.temperature ~= nil then
                local current = caster.components.temperature:GetCurrent()
                if current == nil then
                    return
                end

                if TheWorld.state.season == "summer" then
                    caster.components.temperature:SetTemperature(15) -- 体温
                end
            end
            if caster.components.moisture then
                caster.components.moisture:SetPercent(0)
            end
        end)

        staff:DoTaskInTime(1, function(staff)
            skillobr.originalsword(staff)
        end)
    end
end

-------------------------------地元素
-- 定点范围伤害技能，召唤四个眼球塔输出一定时间，使用后增加50%免伤4分钟

function skillobr.ondirtattack(inst, owner, target, skipsanity) -- 右键后续产生效果
    -- 击中音效
    inst:DoTaskInTime(0.1, function()
        inst.SoundEmitter:PlaySound("dontstarve/wilson/fireball_explo")
    end)

    -- 超级无赖减速定身,没有移动组件则追加伤害
    if target.components.health then
        target.components.health:DoDelta(-0.5 * TUNING.dirt_damage)
    end
    target:DoTaskInTime(0.1, function()
        if target.components.locomotor then
            target.components.locomotor.externalspeedmultiplier = 0.4
        else
            if target.components.health then
                target.components.health:DoDelta(-TUNING.dirt_damage)
            end
        end
    end)
    target:DoTaskInTime(6, function(target)
        if target ~= nil then
            target.components.locomotor.externalspeedmultiplier = 1
        end
    end)
    ----------------------------------打伤害部分

    if target.components.health then
        local max = target.components.health.maxhealth
        local damagesum = 55 + 0.08 * max
        target.components.health:DoDelta(-damagesum)
    end
end

function skillobr.sworddirt(staff, target, pos) -- 地技能释放
    local caster = staff.components.inventoryitem.owner
    if caster.components.obrsword_power.current >= TUNING.FIRECONSUE then
        -- 施法免伤增益
        skillobr.absord(caster)
        staff.SoundEmitter:PlaySound("obrost/obr/obrskillbgm1") -- 音效
        ---闪光标记
        local DIRTFX = SpawnPrefab("archive_lockbox_player_fx")
        DIRTFX.entity:SetParent(caster.entity)
        local pos = target:GetPosition()
        local firebird = SpawnPrefab("crab_king_shine")
        firebird.entity:SetParent(target.entity)

        skillobr.ondirtattack(staff, caster, target)
        -- caster.sg:GoToState("castspell")
        if target.brain then
            target.brain:Stop()
            target:DoTaskInTime(2, function(target)
                target.brain:Start()
            end)
        end
        local function generateRandomBetween0And2Simple()
            return math.random(0, 3 * 1000) / 1000 -- 乘以1000是为了提高精度，然后除以1000回到0到2的范围
        end
        -- 对直线上造成特效攻击 间隔0.2s
        local posself = staff:GetPosition()
        local distance = tools:calcDist(pos.x, pos.z, posself.x, posself.z, true)
        if distance > 4 then
            local dist1 = math.floor(distance)
            for i = 1, (dist1 + 1) do
                if i < (dist1 + 1) then
                    staff:DoTaskInTime(0.4, function(staff)
                        local dirt = SpawnPrefab("singingshell_creature_rockfx")
                        local x1, z1 = tools:findPointOnLine(pos.x, pos.z, posself.x, posself.z, distance, i)
                        dirt.Transform:SetPosition(x1, 0, z1)
                    end)
                else -- 生产一堆沙刺
                    for i = 1, 3 do
                        local ad = math.random(0, 2)
                        local dirt1 = SpawnPrefab("groundpound_fx")
                        dirt1.Transform:SetPosition(pos.x + ad, 0, pos.z + ad)
                    end

                    local time = 0.1 * dist1
                    staff:DoTaskInTime(time, function(staff)
                        for i = 1, 15 do
                            local sand = SpawnPrefab("sandspike")
                            local randomNum2 = generateRandomBetween0And2Simple()
                            local randomNum1 = generateRandomBetween0And2Simple()
                            sand.Transform:SetPosition(pos.x + randomNum2, 0, pos.z + randomNum1)
                            staff:DoTaskInTime(10, function()
                                sand:Remove()
                            end)
                        end
                    end)

                    staff.tower = {}
                    staff:DoTaskInTime(time + 1, function()
                        local sd = 4
                        local function createAndPositionTower(prefixX, prefixZ)
                            local tower = SpawnPrefab("eyeturret")
                            if tower then
                                tower.Transform:SetPosition(pos.x + prefixX * sd, 0, pos.z + prefixZ * sd)
                                tower.components.combat:SetTarget(target)
                                table.insert(staff.tower, tower) -- 将新炮塔添加到 staff.tower 数组中
                            end
                        end

                        -- 创建四个炮塔
                        createAndPositionTower(1, 1)
                        createAndPositionTower(-1, 1)
                        createAndPositionTower(-1, -1)
                        createAndPositionTower(1, -1)
                        staff:DoTaskInTime(60, function()
                            for i, tower in ipairs(staff.tower) do
                                tower:Remove()
                            end
                            staff.tower = {}
                        end)
                    end)
                end
            end
        end

        if caster.components.obrsword_power ~= nil then
            caster.components.obrsword_power:DoDelta(-TUNING.FIRECONSUE)
        end

        -- 技能附带效果：120s的50%免伤以及去除潮湿度

        if caster.components.moisture then
            caster.components.moisture:SetPercent(0)
        end
        if caster.components.debuffable ~= nil and caster.components.debuffable:IsEnabled() and caster.components.combat ~=
            nil and caster.components.health ~= nil and
            not (caster.components.health ~= nil and caster.components.health:IsDead()) and
            not caster:HasTag("playerghost") then
            --  target.components.debuffable:AddDebuff("buff_playerabsorption", "buff_playerabsorption")
            caster.components.health.externalabsorbmodifiers:SetModifier(caster, 0.75, "dust_less_damage_reduction") -- 减伤系数乘以xx倍
        end
        staff:DoTaskInTime(1, function(inst)
            skillobr.originalsword(inst)
        end)

        staff:DoTaskInTime(120, function(staff)
            if caster.components.health ~= nil then
                caster.components.health.externalabsorbmodifiers:RemoveModifier(caster, "dust_less_damage_reduction")
            end
        end)
    end
end

-------------------------------风元素
-- 大龙卷风，吸附，流血，拆迁，
function skillobr.onwindattack(inst, owner, target, skipsanity)
    --  if not target.components.wuyi_karma then target:AddComponent("wuyi_karma") end

    -- target.components.wuyi_karma:DoDelta(2)
    inst:DoTaskInTime(0.1, function()
        inst.SoundEmitter:PlaySound("dontstarve/wilson/fireball_explo")
    end)

    --
    if target.components.health then
        target.components.health:DoDelta(-TUNING.wind_damage)
    end

    if target.components.locomotor then
        target.components.locomotor.externalspeedmultiplier = 0.5
    else
        if target.components.health then
            target.components.health:DoDelta(-TUNING.dirt_damage)
        end
    end

    target:DoTaskInTime(10, function(target)
        if target ~= nil and target.components.locomotor then
            target.components.locomotor.externalspeedmultiplier = 1
        end
    end)
    ----------------------------------打伤害部分
    ---10s流血
    -- local firebird = SpawnPrefab("sword_fx_firebird") -- 施法定身特效
    -- firebird.entity:SetParent(target.entity)
    target.taskfire = target:DoPeriodicTask(0.5, function(target)
        if target.components.health then
            local cu = target.components.health.currenthealth
            local damagesum = 15 + 0.08 * cu
            target.components.health:DoDelta(-damagesum)
        end
    end)
    target:DoTaskInTime(10, function(target)
        if target.taskfire ~= nil then
            target.taskfire:Cancel()
            target.taskfire = nil
        end
        if target.components.health then -- 10%已损失生命值伤害
            local max = target.components.health.maxhealth
            local current = target.components.health.currenthealth
            local havelose = max - current
            local damagesum = 0.1 * havelose
            target.components.health:DoDelta(-damagesum)
        end
    end)
end

function skillobr.swordwind(staff, target, pos) -- 风技能释放
    local caster = staff.components.inventoryitem.owner
    if caster.components.obrsword_power.current >= TUNING.FIRECONSUE then
        -- 施法免伤增益
        skillobr.absord(caster)
        staff.SoundEmitter:PlaySound("obrost/obr/obrskillbgm2") -- 音效
        -- caster.sg:GoToState("castspell")
        local wind = SpawnPrefab("halloween_moonpuff")
        wind.entity:SetParent(caster.entity)
        skillobr.onwindattack(staff, caster, target)
        local function getspawnlocation(inst, target)
            local x1, y1, z1 = inst.Transform:GetWorldPosition()
            local x2, y2, z2 = target.Transform:GetWorldPosition()
            return x1 + .15 * (x2 - x1), 0, z1 + .15 * (z2 - z1)
        end
        staff:DoTaskInTime(1, function(staff)
            -- 生成绿色大龙卷风给我冲
            if caster.components.obrsword_power ~= nil then
                caster.components.obrsword_power:DoDelta(-TUNING.FIRECONSUE)
            end
            local tornado = SpawnPrefab("obsword_wind_torado")

            tornado.WINDSTAFF_CASTER = staff.components.inventoryitem.owner
            tornado.WINDSTAFF_CASTER_ISPLAYER = tornado.WINDSTAFF_CASTER ~= nil and
                tornado.WINDSTAFF_CASTER:HasTag("player")
            tornado.Transform:SetPosition(getspawnlocation(staff, target))
            tornado.components.knownlocations:RememberLocation("target", target:GetPosition())

            if tornado.WINDSTAFF_CASTER_ISPLAYER then
                tornado.overridepkname = tornado.WINDSTAFF_CASTER:GetDisplayName()
                tornado.overridepkpet = true
            end

            -- 技能附带效果：降温以及改动潮湿度
            if caster.components.temperature ~= nil then
                if TheWorld.state.season == "summer" then
                    caster.components.temperature:SetTemperature(15) -- 体温
                end
            end
            if caster.components.moisture then
                caster.components.moisture:SetPercent(0)
            end
        end)

        staff:DoTaskInTime(1, function(inst)
            skillobr.originalsword(inst)
        end)
    end
end

----------------------------------------------------------------光线技能
skillobr.CheckDistsqToPoint = function(target, pos)
    local tx, ty, tz = target.Transform:GetWorldPosition()
    local range = 5 -- 2 * 2
    -- local pos = laser._posdata

    if distsq(tx, tz, pos.x1, pos.z1) <= range then
        return true
    elseif distsq(tx, tz, pos.x2, pos.z2) <= range then
        return true
    elseif distsq(tx, tz, pos.x3, pos.z3) <= range then
        return true
    elseif distsq(tx, tz, pos.x4, pos.z4) <= range then
        return true
    elseif distsq(tx, tz, pos.x5, pos.z5) <= range then
        return true
    end

    return false
end
function skillobr.Laser_DoAttack(laser, inst, caster)
    -- if laser._posdata ~= nil and next(laser._posdata) ~= nil then
    local x, y, z = caster.Transform:GetWorldPosition()
    local radian = math.rad(caster.Transform:GetRotation())
    local radian_z
    local pos = {}
    local new_x, new_z
    local dist

    radian = math.rad(caster.Transform:GetRotation())
    radian_z = math.rad(caster.Transform:GetRotation() - 180)
    x, y, z = caster.Transform:GetWorldPosition()
    new_x = x + 20 * math.cos(radian)
    new_z = z + 20 * math.sin(radian_z)
    dist = tools:calcDist(new_x, new_z, x, z, true)
    -- pos.point1 = tools:findPointOnLine(x, z, new_x, new_z, dist, 2)

    pos.x1, pos.z1 = tools:findPointOnLine(new_x, new_z, x, z, dist, 2)  -- x + 2 * math.cos(radian), z + 2 * math.sin(radian)
    pos.x2, pos.z2 = tools:findPointOnLine(new_x, new_z, x, z, dist, 6)  -- x + 6 * math.cos(radian), z + 6 * math.sin(radian)
    pos.x3, pos.z3 = tools:findPointOnLine(new_x, new_z, x, z, dist, 10) -- x + 10 * math.cos(radian), z + 10 * math.sin(radian)
    pos.x4, pos.z4 = tools:findPointOnLine(new_x, new_z, x, z, dist, 14) -- x + 14 * math.cos(radian), z + 14 * math.sin(radian)
    pos.x5, pos.z5 = tools:findPointOnLine(new_x, new_z, x, z, dist, 18) -- x + 18 * math.cos(radian), z + 18 * math.sin(radian)
    local doer_x, doer_y, doer_z = caster.Transform:GetWorldPosition()

    for _, v in ipairs(TheSim:FindEntities(x, 0, z, 28, { "_combat" },
        { "player", "companion", "abigail", "wall", "glommer", "shadowminion" })) do
        if v ~= nil and v:IsValid() and (v.components.health ~= nil and not v.components.health:IsDead()) and
            v.components.combat ~= nil then
            if skillobr.CheckDistsqToPoint(v, pos) then
                v.components.combat:GetAttacked(caster, 0, inst, nil, {
                    planar = inst.components.planardamage:GetDamage()
                })

                local v_x, _, v_z = v.Transform:GetWorldPosition()                         -- 敌人坐标
                local dist_btw_v_and_doer = tools:calcDist(doer_x, doer_z, v_x, v_z, true) -- 人物到敌人的距离
                local des_x, des_z = tools:findPointOnLine(v_x, v_z, doer_x, doer_z, dist_btw_v_and_doer,
                    dist_btw_v_and_doer + 1)                                               -- 击退
                v.Transform:SetPosition(des_x, 0, des_z)
                local max = v.components.health.maxhealth
                local current = v.components.health.currenthealth
                local havelose = max - current
                local damagesum = 0.01 * havelose + 0.01 * max + 51 -- 1%最大生命值以及1%已损失生命值以及51点基础伤害
                v.components.health:DoDelta(-damagesum)
                local op = 3
                if max < 200 then op = 0.35 end
                caster.components.obrsword_power:DoDelta(-op)

                -- 附加伤害
            end
        end
    end
end

skillobr.StopLaser = function(laser, caster, weapon)
    caster = caster or laser.entity:GetParent()

    if caster ~= nil and caster.components.channelcaster ~= nil then
        caster.components.channelcaster:StopChanneling()
    end

    weapon = weapon or laser._weapon
    if weapon ~= nil then
        weapon.components.rechargeable:Discharge(skillobr.LASER_COOLDOWN)
        -- weapon.components.finiteuses:Use(10)
    end

    if laser ~= nil then
        --[[if laser._updatepos ~= nil then
            laser._updatepos:Cancel()
            laser._updatepos = nil
        end--]]
        if laser._doattack_task ~= nil then
            laser._doattack_task:Cancel()
            laser._doattack_task = nil
        end

        laser:Remove()
        laser = nil
    end
end

skillobr.StopLaserCasting = function(laser, inst, caster)
    if inst._laser ~= nil then
        if inst._laser._doattack_task ~= nil then
            inst._laser._doattack_task:Cancel()
            inst._laser._doattack_task = nil
        end
        inst._laser._overtask = nil

        inst._laser:Remove()
        inst._laser = nil
    end

    if caster.components.channelcaster ~= nil and caster.components.channelcaster:IsChanneling() then
        caster.components.channelcaster:StopChanneling()
    end

    inst.components.rechargeable:Discharge(skillobr.LASER_COOLDOWN)
    -- inst.components.finiteuses:Use(10)
end
function skillobr.Sword_CastLaser(inst, target, pos, caster) ---产生激光的时候改变ui
    if caster == nil then
        return
    elseif not inst.components.rechargeable:IsCharged() then
        if caster.components.talker ~= nil then
            caster.components.talker:Say(GetString(caster, "MAGICITEM_INCD"))
        end
        return
    end
    if caster.components.obrsword_power.current < 75 then
        return
    end
    -- 施法免伤增益
    skillobr.absord(caster)
    caster.niniang_fn:push()
    caster.fx1 = SpawnPrefab("terrariumchest_fx")
    caster.fx1.entity:SetParent(caster.entity)
    caster:DoTaskInTime(8, function()
        if caster.fx1 ~= nil then
            caster.fx1:Remove()
        end
    end)
    -- SendSendModRPCToClientRPC(caster)
    if caster.components.channelcaster ~= nil and not caster.components.channelcaster:IsChanneling() and inst._laser ==
        nil then
        caster.components.channelcaster:StartChanneling()

        inst._laser = SpawnPrefab("fx_laserbeem_blue_particle")
        inst._laser.entity:SetParent(caster.entity)
        inst._laser.Transform:SetPosition(0, 1.5, 0)
        inst._laser.Transform:SetScale(2, 2, 2)
        inst._laser._weapon = inst

        if inst._laser._doattack_task == nil then
            inst._laser._doattack_task = inst._laser:DoPeriodicTask(0.3, skillobr.Laser_DoAttack, 0.1, inst, caster)
        end

        inst._laser:ListenForEvent("unequipped", function()
            if inst._laser._overtask ~= nil then
                inst._laser._overtask:Cancel()
                inst._laser._overtask = nil
            end
            skillobr.StopLaserCasting(inst, caster)
        end, inst)

        inst._laser:ListenForEvent("stopchannelcast", function()
            skillobr.StopLaserCasting(inst, caster)
        end, caster)

        if inst._laser._overtask == nil then
            inst._laser._overtask = inst._laser:DoTaskInTime(8, skillobr.StopLaserCasting, inst, caster)
        end
    end
end

return skillobr
